<template>
  <div v-if="dialogVisble">
    <el-dialog :title="title" :visible.sync="dialogVisble" :before-close="handleClose"
               :close-on-click-modal=false>
      <el-form :model="form" label-position="right" label-width="100px" ref="form" :rules="rules">
        <el-form-item label="步骤名称" prop="stepName">
          <el-input v-model="form.stepName" autocomplete="off" @input="onInput('stepName')" maxlength="50"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="操作类型" prop="func">
          <el-cascader
            style="width: 100%"
            v-model="form.func"
            filterable
            :show-all-levels="false"
            ref="cascade"
            :options="options"
            placeholder="请选择操作"
            @change="changeValue"></el-cascader>
        </el-form-item>
        <el-form-item label="操作对象" prop="status" v-if="isElement">
          <el-radio-group v-model="form.optElement.status" @change="changeRadio">
            <el-radio label="0">元素库选择</el-radio>
            <el-radio label="1">定位选择</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="" v-if="isElement && form.optElement.status==='0'" prop="elLibrarySelect">
          <el-select v-model="form.optElement.chooseName" placeholder="请选择元素模块" ref="selectModuleId"
                     style="width: 50%;margin-right: -5px;">
            <el-input v-model="treeFilter" class="input" placeholder="此处键入关键词搜索查询" prefix-icon="el-icon-search"
                      style="padding: 5px" clearable/>
            <el-option hidden :key="form.optElement.moduleId" value="一级菜单"
                       :label="form.optElement.chooseName"></el-option>
            <el-tree
              ref="tree"
              :data="moduleTree"
              :props="defaultProps"
              @node-click="nodeOnclick"
              :expand-on-click-node="false"
              :check-on-click-node="true"
              :filter-node-method="filterNode"
              filterable
              @change="changeClearValidate('elLibrarySelect')"
            />
          </el-select>
          <el-select v-model="form.optElement.el" placeholder="请选择元素" v-if="form.optElement.status==='0'"
                     style="width: 50%"
                     @change="changeEl" filterable>
            <el-option v-for="item in elementOptions" :key="item.id" :label="item.name" :value="item.id"/>
          </el-select>
        </el-form-item>
        <div v-if="isElement && form.optElement.status==='1'">
          <el-form-item label="" prop="locationSelect">
            <el-input placeholder="请输入元素定位表达式" v-model="form.optElement.expression" @input="onInput('locationSelect')">
              <el-select v-model="form.optElement.by" slot="prepend" placeholder="请选择定位方式" style="width: 150px;"
                         @change="$forceUpdate()">
                <el-option v-for="item in bys" :key="item.value" :label="item.label" :value="item.value"/>
              </el-select>
            </el-input>
          </el-form-item>
          <el-form-item>
              <span slot="label">
                 <span class="span-box">
                   <span>同步元素</span>
                    <el-tooltip
                      style="diaplay:inline" effect="dark"
                      placement="top">
                      <div slot="content">新建步骤，填写该行参数后，保存后将会同步保存到元素管理的元素库内</div>
                      <i class="el-icon-info"/>
                    </el-tooltip>
                 </span>
               </span>
            <el-select v-model="form.optElement.chooseName" placeholder="请选择元素模块" ref="selectModuleId"
                       style="width: 50%;margin-right: -5px;">
              <el-input v-model="treeFilter" class="input" placeholder="此处键入关键词搜索查询" prefix-icon="el-icon-search"
                        style="padding: 5px" clearable/>
              <el-option hidden :key="form.optElement.moduleId" value="一级菜单"
                         :label="form.optElement.chooseName"></el-option>
              <el-tree
                ref="tree"
                :data="moduleTree"
                :props="defaultProps"
                @node-click="nodeOnclick"
                :expand-on-click-node="false"
                :check-on-click-node="true"
                :filter-node-method="filterNode"
                filterable
                @change="changeClearValidate('elLibrarySelect')"
              />
            </el-select>
            <el-input v-model="form.optElement.elName" autocomplete="off" @input="onInput('stepName')" maxlength="50"
                      style="width: 50%"></el-input>
          </el-form-item>
        </div>
        <el-form-item :label="item.paramName" prop="optData" v-for="(item) in form.optData" :key="item.id"
                      v-if="isData">
          <el-input v-model="item.value" :placeholder="item.description" @input="onInput('optData')"
                    v-if="!isFile" type="textarea"></el-input>
          <el-upload class="upload-demo" :file-list="item.fileList" :before-upload="beforeUpload"
                     :http-request="uploadFile"
                     accept=".xls, .xlsx, .png, .pdf, .jpg, .jpeg, .md, .txt, .doc, .docx, .html, .htm"
                     v-if="isFile"
                     :on-remove="removeFile" :on-exceed="handleExceed" drag action="" :limit="1" ref="upload">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            <div class="el-upload__tip" slot="tip">只能上传单个后缀为 xls, xlsx, png, pdf, jpg, jpeg, md, txt, doc, docx, html,
              htm 的文件，且不超过5M
            </div>
          </el-upload>
        </el-form-item>
        <el-form-item label="启用状态">
          <template slot-scope="scope">
            <el-switch v-model="form.status" active-value="1" inactive-value="0"></el-switch>
          </template>
        </el-form-item>
        <el-form-item label="行背景色">
          <el-color-picker v-model="form.backgroundColor" :predefine="predefineColors" show-alpha></el-color-picker>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="save('form')">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {guid} from '@/utils/util'

export default {
  name: "cuDialog",
  props: {
    dialogVisble: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: ""
    },
    editStepData: {
      type: Object,
      default: {}
    },
    order: {
      type: Number,
      default: 0
    }
  },
  data() {
    let checkElLibrarySelect = (rule, value, callback) => {
      if (this.form.optElement.chooseName === "" || this.form.optElement.el === "") {
        callback(new Error('chooseName-el不能为空'));
      } else {
        callback();
      }
    };
    let checkLocationSelect = (rule, value, callback) => {
      if (this.form.optElement.by === "" || this.form.optElement.expression === "") {
        callback(new Error('by-expression不能为空'));
      } else {
        callback();
      }
    };
    let checkOptData = (rule, value, callback) => {
      this.form.optData.forEach(item => {
        if (!item.value) {
          callback(new Error('optData不能为空'));
        } else {
          callback();
        }
      })
    };
    return {
      treeFilter: "",
      isElement: false,
      isData: false,
      isFile: false,
      projectId: window.sessionStorage.getItem("projectId"),
      predefineColors: [
        'rgba(241, 221, 116, 0.3)',
        'rgba(144, 238, 144, 0.3)',
        'rgba(241, 183, 112, 0.3)',
        'rgba(12, 243, 247, 0.3)',
        'rgba(16, 126, 234, 0.2)',
        'rgba(225, 22, 150, 0.2)'
      ],
      id: "",
      form: {
        id: "",
        stepName: "",
        func: "",
        optName: "",
        optElement: {
          status: "0",
          by: "",
          expression: "",
          moduleId: "",
          chooseName: "",
          el: "",
          elLabel: "",
          nodeIds: [],
          elName: "",
        },
        optData: [{
          type: "",
          paramName: "",
          description: "",
          fileName: "",
          fileList: [],
          value: "",
        }],
        status: "1",
        backgroundColor: ""
      },
      rules: {
        stepName: [{required: true, message: '名称不能为空', trigger: 'blur'}],
        func: [{required: true, message: '操作选项不能为空', trigger: 'blur'}],
        status: [{required: true, message: '操作对象不能为空', trigger: 'blur'}],
        optData: [{required: true, validator: checkOptData, message: '操作数据不能为空', trigger: 'blur'}],
        elLibrarySelect: [{
          required: true,
          validator: checkElLibrarySelect,
          message: '元数库和元素名称都不能为空',
          trigger: 'blur'
        }],
        locationSelect: [{required: true, validator: checkLocationSelect, message: '定位方式和表达式都不能为空', trigger: 'blur'}],
      },
      options: [],
      bys: [
        {label: "xpath", value: "xpath"},
        {label: "id", value: "id"},
        {label: "name", value: "name"},
        {label: "tagName", value: "tagName"},
        {label: "className", value: "className"},
        {label: "cssSelector", value: "cssSelector"},
        {label: "linkText", value: "linkText"},
        {label: "partialLinkText", value: "partialLinkText"},
        {label: "byTitle", value: "byTitle"},
        {label: "byValue", value: "byValue"},
        {label: "withText", value: "withText"},
        {label: "text", value: "text"},
      ],
      //下拉树
      defaultProps: {label: "name", children: "children"},
      moduleTree: [],
      elementOptions: [],
    }
  },
  mounted() {
    this.getOperationList();
    this.getTreeNode();
  },
  created() {
    if (this.editStepData) {
      if (this.editStepData.optData.length > 0) {
        this.isData = true
        // 编辑回显上传文件名称
        if (this.editStepData.func === "execUpload") {
          this.isFile = true
          this.editStepData.optData[0].fileList = [{name: this.editStepData.optData[0].fileName}]
        }
      }
      if (this.editStepData.optElement.by || this.editStepData.optElement.el) {
        if (this.editStepData.optElement.nodeIds.length > 0) {
          this.getAllElementList(this.editStepData.optElement.nodeIds);
        }
        this.isElement = true
      }
      this.form = JSON.parse(JSON.stringify(this.editStepData))
    }
  },
  methods: {
    filterNode(value, data) {
      if (!value) return true
      const filterRes = data.name.indexOf(value) !== -1
      return filterRes
    },
    changeClearValidate(value) {
      this.$refs["form"].clearValidate(value);
    },
    changeRadio() {
      this.form.optElement.by = ""
      this.form.optElement.expression = ""
      this.form.optElement.moduleId = ""
      this.form.optElement.chooseName = ""
      this.form.optElement.el = ""
      this.form.optElement.elLabel = ""
      this.form.optElement.elName = ""
      this.form.optElement.nodeIds = []
    },
    changeEl(data) {
      // this.$forceUpdate();
      this.elementOptions.map(item => {
        if (item.id === data) {
          this.form.optElement["elLabel"] = item.name;
          this.form.optElement["by"] = item.locationType;
          this.id = data
          this.form.optElement["expression"] = "$[" + data + "]";
        }
      })
      this.changeClearValidate('elLibrarySelect')
    },
    getTreeNode() {
      this.api({
        url: `/getPageModuleTree/${this.projectId}`,
        method: "get"
      }).then(resp => {
        this.moduleTree = resp.list;
      });
    },
    nodeOnclick(data) {
      // 配置树形组件点击节点后，设置选择器的值，配置组件的数据
      this.form.optElement.chooseName = data.name
      this.form.optElement.moduleId = data.id
      let nodeIds = [];
      this.getChildNodeId(data, nodeIds);
      this.getAllElementList(nodeIds);
      this.form.optElement.nodeIds = nodeIds;
      this.$refs.selectModuleId.blur()
    },
    getAllElementList(nodeIds) {
      this.api({
        pageRow: 9999,
        url: "/getAllElementList",
        method: "post",
        data: {
          keywords: "",
          pageNum: 1,
          projectId: this.projectId,
          moduleId: nodeIds
        },
      }).then(resp => {
        this.elementOptions = resp;
      });
    },
    getChildNodeId(rootNode, nodeIds) {
      //递归获取所有子节点ID
      nodeIds.push(rootNode.id);
      if (rootNode.children) {
        for (let i = 0; i < rootNode.children.length; i++) {
          this.getChildNodeId(rootNode.children[i], nodeIds);
        }
      }
    },
    onInput(value) {
      this.$forceUpdate();
      this.$refs["form"].clearValidate(value);
    },
    changeValue(value) {
      this.isFile = !!value.includes("execUpload")
      let nodesInfo = this.$refs['cascade'].getCheckedNodes()[0].data
      this.form.stepName = nodesInfo.label;
      this.form.func = nodesInfo.value;
      this.form.optName = nodesInfo.label;
      if (nodesInfo.element === "0") {
        this.isElement = false
        this.changeRadio()
      } else {
        this.isElement = true;
      }
      if (nodesInfo.data !== "[]") {
        this.isData = true
        this.form.optData = JSON.parse(nodesInfo.data);
      } else {
        this.isData = false
        this.form.optData = []
      }
      this.changeClearValidate("stepName")
      this.changeClearValidate("func")
    },
    getOperationList() {
      this.api({
        url: "/getOperationList",
        method: "get"
      }).then(resp => {
        this.options = resp;
      });
    },
    handleClose() {
      this.$emit("closeDialog")
    },
    save(ruleForm) {
      this.$refs[ruleForm].validate(valid => {
        if (valid) {
          if (this.title === "新建步骤") {
            this.form.id = guid();
            this.form.parent_id = 0;
            this.form.children = [];
            this.form.order = this.order;
            this.form.caseId = sessionStorage.getItem("caseId")
            this.form.caseName = sessionStorage.getItem("caseName")
          } else {
            this.$emit("addStep", this.form);
            this.handleClose();
          }
          // 如果模块id和元素名词存在 则新建该元素
          if (this.form.optElement.elName && this.form.optElement.moduleId && this.form.optElement.el === "") {
            let data = {};
            data.createUser = this.$store.state.user.userId;
            data.projectId = this.projectId;
            data.expression = this.form.optElement.expression;
            data.moduleId = this.form.optElement.moduleId;
            data.name = this.form.optElement.elName;
            data.locationType = this.form.optElement.by;
            this.api({url: "/addElement", method: "post", data: data}).then(resp => {
              this.api({
                url: "/getAllElementList",
                method: "post",
                data: {keywords: "", pageRow: 9999, pageNum: 1, projectId: this.projectId, moduleId: [data.moduleId]},
              }).then(resp => {
                this.elementOptions = resp;
                this.form.optElement.status = "0"
                this.form.optElement.el = this.elementOptions[0].id
                this.form.optElement.elLabel = this.elementOptions[0].name
                this.form.optElement.expression = "$[" + this.elementOptions[0].id + "]";
                this.$emit("addStep", this.form);
                this.handleClose();
              });
            })
          } else {
            this.$emit("addStep", this.form);
            this.handleClose();
          }
        }
      })
    },
    // 上传前判断格式和大小
    beforeUpload(file) {
      let FileExt = file.name.replace(/.+\./, "");
      if (['xls', 'xlsx', 'png', 'pdf', 'jpg', 'jpeg', 'md', 'txt', 'doc', 'docx', 'html', 'htm'].indexOf(FileExt.toLowerCase()) === -1) {
        this.$message({
          type: 'warning',
          message: '请上传后缀名为xls、xlsx、png、pdf、jpg、jpeg、md、txt、doc、docx、html、htm的附件！'
        });
        return false;
      }
      if (file.size > 5 * 1024 * 1024) {
        this.$message.warning('文件大小超过5M 无法上传');
        return false;
      }
      return true;
    },
    handleExceed() {
      this.$message.warning('一次最多只能上传一个文件');
    },
    uploadFile(option) {
      let FormDatas = new FormData()
      FormDatas.append('file', option.file);
      this.form.optData[0].fileList = []
      this.form.optData[0].fileList.push(option.file);
      this.form.optData[0].fileName = option.file.name;
      this.$refs.form.validateField('fileList');
      this.api({
        url: "/upload",
        method: "post",
        data: FormDatas,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(resp => {
        if (resp.code === "500") {
          this.form.optData[0].fileList = [];
        } else {
          this.form.optData[0].value = resp
          this.changeClearValidate("optData")
        }
      });
      this.changeClearValidate("fileList")
    },
    removeFile() {
      this.form.optData[0].fileList = [];
      this.form.optData[0].value = "";
    }
  },
  watch: {
    // 搜索过滤，监听input搜索框绑定的treeFilter
    treeFilter(val) {
      this.$refs.tree.filter(val)
    }
  }
}
</script>

<style scoped>
.tip {
  padding: 3px 5px;
  font-size: 16px;
  border-radius: 0;
  border-left: 4px solid #1f2d3d;
  margin: 0 5px 10px;
}

.row {
  padding: 0 20px;
}
</style>
